import math
import struct


class NumUtils:

    PRECISION = 0.00001 ##浮点精度

    @staticmethod
    def float(value: float, precision=2):
        """
        指定精度值
        """
        base_p = math.pow(10, precision)
        return int(value * base_p) / base_p

    @staticmethod
    def format_percent(value:float):
        return f"{100 * value:.1f}%"

    @staticmethod
    def is_equal(f1:float,f2:float,precision:float=PRECISION):
        """
        f1 == f2
        """
        return abs(f1-f2) <= precision

    @staticmethod
    def is_larger_or_equal(f1: float, f2: float, precision: float = PRECISION):
        '''
         f1 >= f2
        '''
        return f1 > f2 or  abs(f1-f2) <= precision

    @staticmethod
    def is_smaller_or_equal(f1: float, f2: float, precision:float =PRECISION):
        '''
         f1 <= f2
        '''
        return f1 < f2 or  abs(f1-f2) <= precision

    @staticmethod
    def round(f:float,precision = 0.01):
        assert precision <= 1
        return int(f / precision + 0.5) * precision

    @staticmethod
    def ceil(f: float, precision=0.01):
        f1 = f / precision
        f2 = int(f1)
        if f1 - f2 > 0:
            f2 +=1
        return f2 * precision

    @staticmethod
    def floor(f: float, precision=0.01):
        return int(f / precision) * precision

    @staticmethod
    def is_over_precision(f:float,precision = 0.01):
        """
        是否超过指定的浮点精度：
        """
        base = int(NumUtils.round(1/precision,1))
        v = int(f * base)
        f = f * base
        return v != f


if __name__ == '__main__':

    print(f"{NumUtils.floor(3424.341)}")
    print(f"{NumUtils.is_over_precision(3424.341,0.01)}")
    print(f"{NumUtils.is_over_precision(0.34100003,0.001)}")
    print(f"{NumUtils.is_over_precision(8194.63,0.01)}")



    ##[时间: int16, volume: int32, open: int16:, high: int16, lowint16, closeint16]
    ##U_INT8,       U_INT16,    U_INT_32,       U_INT64
    ## b(1),        h(2),       i(4),           q(8)
    # (-128-127)   (- 32768, 32767) (- 2147483648,2147483647)  (-
    def get_struce_code(value):
        if value >-128 and value < 127:
            return 'b'
        elif value > -32768 and value < 32767:
            return 'h'
        elif value > -2147483648 and value < 2147483647:
            return 'i'
        return 'q'

    # 编号 | structcode, 占用字节
    symbols = ['b','h','i','q']
    codes = [1,2,4,8]



    def ttt(size,symbols,codes,index,structcode,byte_len,lists:[]):
        if index >= size:
            lists.append([structcode,byte_len])
            return
        count = 1 if index < 1 else 2
        for i in range(0,len(symbols)):
            for j in range(0,count):
                structcode += symbols[i]
                byte_len += codes[i]
            ttt(size,symbols,codes,index+1,structcode,byte_len,lists)
            for j in range(0,count):
                structcode = structcode[0:-1]
                byte_len -= codes[i]
    lists = []
    ttt(3,symbols,codes,0,"H",2,lists)
    print(f"ttt: = {len(lists)}")
    print(f"TYPE_100_STRUCET_CODE = {[ ss[0] for ss in lists ]}")
    print(f"TYPE_100_STRUCET_CODE_BYTE_LENGTH = {[ ss[1] for ss in lists ]}")






    import io

    output = io.BytesIO()

    def pack_value(values):
        struct_code = "i"*len(values)
        v1 = struct.pack(struct_code,*values)
        v2 = struct.pack(f"<{struct_code}",*values)
        v3 = struct.pack(f"!{struct_code}",*values)
        print(f"v1:{len(v1)}, v2:{len(v2)}, v3:{len(v3)}")


    values = [0, 234234, 3423, 423, 345, 34500]
    values2 = [134, 0, 0, 0, 0, 0]
    pack_value(values)
    pack_value(values2)

    #print(f"value: {value2}")
    #print(f"{len(lists)}")